package com.example.test.反射;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * @author 晓果冻
 * @version 1.0
 * @date 2022/5/24 14:20
 */
public class Main {
    public static void main(String[] args) throws Exception {
        //方式一
        Class userClass = Class.forName("com.example.test.反射.User");
        System.out.println(userClass);
        System.out.println("*************");
        //方式二
        Class userClass2 = User.class;
        System.out.println(userClass);
        System.out.println("*************");
        //方式三
        User user = new User();
        Class userClass3 = user.getClass();
        System.out.println(userClass3);
        System.out.println("***************");

        //调用无参构造函数
        User user1 = (User) userClass2.newInstance();
        //调用有参构造函数
        Constructor<?> declaredConstructor =userClass2.getDeclaredConstructor(String.class,Integer.class,String.class);
        User user2 = (User)declaredConstructor.newInstance("张三",28,"张三丰");
        System.out.println(user2.toString());
        System.out.println(user1==user2);

        //公有属性查找、赋值
        User user4 = (User)userClass.newInstance();
        Field publicName = userClass.getDeclaredField("publicName");
        publicName.set(user4,"晓果冻");
        System.out.println(user4.toString());

        //私有属性查找、赋值
        User user5 = (User)userClass.newInstance();
        Field name = userClass.getDeclaredField("name");
        //反射访问私有属性
        name.setAccessible(true);
        name.set(user5,"晓果冻5");
        System.out.println(user5.toString());
        System.out.println(user4==user5);

        //获取所有方法
        User user6 = (User)userClass.newInstance();
        //获取所有方法
        Method[] methods = userClass.getMethods();
        for(Method method:methods){
            System.out.println(method);
        }

        //只能获取公共的方法
        Method getName = userClass.getMethod("getName");

        Method sumMethod = userClass.getDeclaredMethod("sum",Integer.class,Integer.class);
        sumMethod.setAccessible(true);
        Object total = sumMethod.invoke(user6,1,2);
        System.out.println(total);


        //反射越过泛型检查 只在编译器检查
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("晓果冻");
        Class<? extends ArrayList> aClass =  arrayList.getClass();
        Method addMethod = aClass.getDeclaredMethod("add", Object.class);
        addMethod.invoke(arrayList,1);
        System.out.println(arrayList);


    }
}
